﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using CarolLib.Control;

namespace CarolLib
{
    public partial class Form1 : Form
    {
        private List<Result> Results;
        private List<Result> tempResults;
        private int stateStart;
        private int stateMark;
        private bool CheckNew;
        private object locker = new object();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Results = new List<Result>();
        }

        private void btnGo_Click(object sender, EventArgs e)
        {
            GetInfo(false);
        }

        [Obsolete]
        private void GetInfoOld(bool checkNew)
        {
            #region Download

            Config config = new Config(this.tbCong.Text.Trim()
                , this.tbDao.Text.Trim()
                , this.tbFrom.Text.Trim()
                , this.tbTo.Text.Trim()
                , this.dpDate.Value
                );

            List<Result> results = new List<Result>();

            foreach (var item in config)
            {
                using (WebClient wc1 = new WebClient())
                {
                    wc1.Encoding = item.Encoding;
                    string text = wc1.DownloadString(item.Url);
                    MatchCollection mc = Regex.Matches(text, item.RegexPattern, RegexOptions.Multiline);
                    if (mc.Count == 0)
                    {
                        ShowTooltip(item.Name + "没有这天的票");
                    }
                    int i = 0;
                    foreach (Match m in mc)
                    {
                        if (m.Success)
                        {
                            results.Add(new Result()
                            {
                                网站 = item.Name,
                                序号 = i++,
                                Url = string.Format(item.UrlTemp, m.Groups[1].Value),
                                信息 = m.Groups[2].Value.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("&nbsp;", string.Empty)
                            });
                        }
                    }
                }
            }

            #endregion

            this.dataGridView1.DataSource = new SortableBindingList<Result>(results);
            this.dataGridView1.Columns["网站"].Width = 80;
            this.dataGridView1.Columns["序号"].Width = 80;
            this.dataGridView1.Columns["张数"].Width = 80;
            this.dataGridView1.Columns["车次"].Width = 80;
            this.dataGridView1.Columns["Url"].Visible = false;

            #region CheckNew

            if (checkNew)
            {
                StringBuilder sb = new StringBuilder();
                var oldGroups = this.Results.GroupBy(r => r.网站);
                var newGroups = results.GroupBy(r => r.网站);
                foreach (var group in newGroups)
                {
                    if (group.Count() > oldGroups.Where(g => g.Key == group.Key).Count())
                    {
                        var list = group.ToList();
                        int newCount = 0;
                        if (oldGroups.Where(g => g.Key == group.Key).Count() > 0)
                        {
                            var oldNo1 = oldGroups.Where(g => g.Key == group.Key).First().OrderBy(r => r.序号).First();

                            try
                            {
                                newCount = list.Find(r => r.信息 == oldNo1.信息).序号;
                            }
                            catch
                            {
                                newCount = group.Count() - oldGroups.Where(g => g.Key == group.Key).Count();
                            }
                        }
                        else
                        {
                            newCount = list.Count();
                        }

                        if (newCount > 0)
                        {
                            sb.AppendLine(string.Format("{0} 新增转让信息 {1} 条：", group.Key, newCount));
                            for (int i = 0; i < newCount; i++)
                            {
                                sb.AppendLine(list[i].信息);
                            }
                        }
                    }
                }
                string msg = sb.ToString();
                if (!string.IsNullOrEmpty(msg))
                {
                    this.ShowTooltip(msg);
                }
            }

            #endregion

            this.Results = results;

            this.toolStripStatusLabel1.Text = string.Format("最后更新时间：{0} 共计{1}条转让信息", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), Results.Count);
        }

        private void GetInfo(bool checkNew)
        {
            #region Download

            Config config = new Config(this.tbCong.Text.Trim()
                , this.tbDao.Text.Trim()
                , this.tbFrom.Text.Trim()
                , this.tbTo.Text.Trim()
                , this.dpDate.Value
                );

            tempResults = new List<Result>();
            stateStart = 0;
            stateMark = config.Count;
            this.CheckNew = checkNew;

            foreach (var item in config)
            {
                using (WebClient wc1 = new WebClient())
                {
                    wc1.Encoding = item.Encoding;
                    wc1.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc1_DownloadStringCompleted);
                    wc1.DownloadStringAsync(new Uri(item.Url), item);
                }
            }

            #endregion

            this.toolStripStatusLabel1.Text = "正在fucking铁道部，请等待...";
        }

        private void wc1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            Site item = e.UserState as Site;
            string text = e.Result;
            MatchCollection mc = Regex.Matches(text, item.RegexPattern, RegexOptions.Multiline);
            if (mc.Count == 0)
            {
                ShowTooltip(item.Name + "没有这天的票");
            }
            int i = 0;
            lock (locker)
            {
                foreach (Match m in mc)
                {
                    if (m.Success)
                    {
                        tempResults.Add(new Result()
                        {
                            网站 = item.Name,
                            序号 = i++,
                            Url = string.Format(item.UrlTemp, m.Groups[1].Value),
                            信息 = m.Groups[2].Value.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("&nbsp;", string.Empty)
                        });
                    }
                }
                stateStart += 1;
            }

            if (stateStart == stateMark)
            {
                GoContinue();
            }
        }

        private void GoContinue()
        {
            this.dataGridView1.DataSource = new SortableBindingList<Result>(tempResults);
            this.dataGridView1.Columns["网站"].Width = 80;
            this.dataGridView1.Columns["序号"].Width = 80;
            this.dataGridView1.Columns["张数"].Width = 80;
            this.dataGridView1.Columns["车次"].Width = 80;
            this.dataGridView1.Columns["Url"].Visible = false;

            #region CheckNew

            if (CheckNew)
            {
                StringBuilder sb = new StringBuilder();
                var oldGroups = this.Results.GroupBy(r => r.网站);
                var newGroups = tempResults.GroupBy(r => r.网站);
                foreach (var group in newGroups)
                {
                    var list = group.ToList();
                    List<Result> news = null;

                    if (oldGroups.Where(g => g.Key == group.Key).Count() == 0)
                    {
                        news = list;
                    }
                    else
                    {
                        var dic = oldGroups.Where(g => g.Key == group.Key).First().ToDictionary(r => r.Url);

                        news = list.Where(r => !dic.ContainsKey(r.Url)).ToList();
                    }

                    if (news.Count > 0)
                    {
                        sb.AppendLine(string.Format("{0} 新增转让信息 {1} 条：", group.Key, news.Count));
                        foreach (var item in news)
                        {
                            sb.AppendLine(item.信息);
                        }
                    }
                }

                string msg = sb.ToString();
                if (!string.IsNullOrEmpty(msg))
                {
                    this.ShowTooltip(msg);
                }
            }

            #endregion

            this.Results = tempResults;

            this.toolStripStatusLabel1.Text = string.Format("最后更新时间：{0} 共计{1}条转让信息", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), Results.Count);
        }

        private void dataGridView1_DoubleClick(object sender, EventArgs e)
        {
            var current = this.dataGridView1.SelectedRows;
            if (current.Count > 0)
            {
                string web = current[0].Cells["网站"].Value.ToString();
                int idx = int.Parse(current[0].Cells["序号"].Value.ToString());

                var record = this.Results.Where(r => (r.网站 == web) && (r.序号 == idx)).FirstOrDefault();
                if (record != null)
                {
                    this.webBrowser1.Url = new Uri(record.Url);
                    this.tabControl1.SelectedIndex = 1;
                }
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.Visible)
            {
                this.Hide();
                this.ShowInTaskbar = false;
            }
            else
            {
                this.Show();
                this.ShowInTaskbar = true;
            }
        }

        private void ShowTooltip(string msg)
        {
            this.notifyIcon1.ShowBalloonTip(100000, "抢票提示", msg, ToolTipIcon.Info);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            GetInfo(true);
        }

        private void ckMonit_CheckedChanged(object sender, EventArgs e)
        {
            if (Results.Count==0)
            {
                GetInfo(false);
            }
            this.timer1.Enabled = ckMonit.Checked;
        }

        private void notifyIcon1_BalloonTipClicked(object sender, EventArgs e)
        {
            this.Show();
        }

        private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("双击表中的记录会在右边打开对应的网页");
            sb.AppendLine("双击右下角图标能隐藏窗口，再次双击则打开");
            sb.AppendLine("“序号”越小的信息越新");
            sb.AppendLine("信息每分钟检测一次，如果有新信息则会在右下角弹出");
            sb.AppendLine("");
            sb.AppendLine("作者博客:http://blodfox777.cnblogs.com");
            MessageBox.Show(sb.ToString());
        }
    }

    public class Site
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public string RegexPattern { get; set; }
        public Encoding Encoding { get; set; }
        public string UrlTemp { get; set; }
        public string[] Keys { get; set; }
        public int Numbers { get; set; }
    }

    public class Result
    {
        public string 网站 { get; set; }
        public int 序号 { get; set; }
        public string 车次
        {
            get
            {
                var mc = Regex.Matches(this.信息, "[A-Z]{1}[0-9]{2,4}");
                if (mc.Count == 0)
                    return string.Empty;
                return mc[0].Value;
            }
        }
        public string 张数
        {
            get
            {
                var mc = Regex.Matches(this.信息, "[0-9]{1}张");
                if (mc.Count == 0)
                    return string.Empty;
                return mc[0].Value;
            }
        }
        public string 信息 { get; set; }
        public string Url { get; set; }
    }

    public class Config : List<Site>
    {
        public string From { get; set; }
        public string To { get; set; }
        public string Efrom { get; set; }
        public string Eto { get; set; }
        public DateTime Date { get; set; }

        public Config(string from, string to, string efrom, string eto, DateTime date)
        {
            this.From = from;
            this.To = to;
            this.Efrom = efrom;
            this.Eto = eto;
            this.Date = date;

            this.Add(new Site()
            {
                Name = "赶集网",
                Url = "http://sh.ganji.com/piao/zz_" + From + "-" + To + "/" + Date.ToString("yyyyMMdd") + "/",
                RegexPattern = @"<a href=\""/piao/(.*?)\"" target=\""_blank\"">(.*?)</a>",
                Encoding = Encoding.UTF8,
                UrlTemp = "http://sh.ganji.com/piao/{0}"
            });

            this.Add(new Site()
            {
                Name = "58同城",
                Url = "http://www.58.com/huochepiao/" + Efrom + "-" + Eto + "/?StartTime=" + Date.ToString("yyyyMMdd") + "00",
                RegexPattern = @"<a class=""t"" target=""_blank"" href=""(.*?)"">([\s\S]*?)</a>",
                Encoding = Encoding.UTF8,
                UrlTemp = "{0}"
            });

            this.Add(new Site()
            {
                Name = "酷讯网",
                Url = "http://huoche.kuxun.cn/zhuanrang-" + Efrom + "-" + Eto + ".html?date=" + Date.ToString("M-dd"),
                RegexPattern = @"<span class=""col_11 left""><a target=""_blank"" href=""(.*)"">(.*)</a>",
                Encoding = Encoding.UTF8,
                UrlTemp="{0}"
            });
        }
    }
}
